// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import { AudioMgr } from '../controller/AudioMgr';
import GameCtrl from '../controller/GameCtrl';
import { BaseComponent } from '../core/BaseComponent';
import { Forward, GameState, pInfo, PlayerInput, ServerMessage } from '../define/GameDefine';
import { UICommandKey } from '../define/UICommand';
import SceneMgr from '../manager/SceneMgr';
import ViewMgr from '../manager/ViewMgr';
import { WebSocketClient } from '../sockets/WebSocketClient';
import { gameData } from '../tool/GameData';
import MapView from '../view/MapView';

const { ccclass, property } = cc._decorator;

@ccclass
export default class GameScene extends BaseComponent {
  @property(MapView)
  mapView: MapView = null;

  @property(cc.Node)
  loginView: cc.Node = null;

  @property(cc.EditBox)
  editBox: cc.EditBox = null;

  @property(cc.Node)
  startBtn: cc.Node = null;

  @property(cc.Node)
  descBtn: cc.Node = null;

  @property(cc.Node)
  devBtn: cc.Node = null;

  @property(cc.Label)
  waitLabel: cc.Label = null;

  @property(cc.Node)
  descView: cc.Node = null;

  @property(cc.Node)
  devView: cc.Node = null;

  // LIFE-CYCLE CALLBACKS:

  onLoad() {
    cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
    cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
    ViewMgr.ins.addEventListener(UICommandKey.onFindGame, this.onFindGame, this);
    ViewMgr.ins.addEventListener(UICommandKey.onGetFrame, this.tick, this);
  }

  start() {
    SceneMgr.inst.init();
    GameCtrl.inst.gameInit();
    this.waitLabel.node.active = false;
  }

  private onClickStart(): void {
    let inputName: string;
    //let inputName: string = this.editBox.string;
    AudioMgr.inst.playSoundLocal('eatGold');
    inputName = 'name' + Math.floor(Math.random() * 10000000);
    GameCtrl.inst.startGame(inputName);
    this.startBtn.active = false;
    this.descBtn.active = false;
    this.devBtn.active = false;
    this.waitLabel.node.active = true;
    //ViewMgr.ins.hint("背包容量不够");
  }

  private onFindGame(): void {
    this.loginView.active = false;
    ViewMgr.ins.emit(UICommandKey.gameStart);
  }

  private itemInit(): void {}

  private onKeyDown(event): void {
    GameCtrl.inst.playerInput(event.keyCode);

    // switch (event.keyCode) {
    //   case cc.macro.KEY.up:
    //     break;
    //   case cc.macro.KEY.down:
    //     GameCtrl.inst.playerInput(playerInput.Down);
    //     break;
    //   case cc.macro.KEY.left:
    //     GameCtrl.inst.playerInput(playerInput.Left);
    //     break;
    //   case cc.macro.KEY.right:
    //     GameCtrl.inst.playerInput(playerInput.Right);
    //     break;
    //   case cc.macro.KEY.space:
    //     GameCtrl.inst.playerInput(playerInput.Space);
    //     break;
    // }
  }

  private onKeyUp(event): void {
    GameCtrl.inst.playerCancel(event.keyCode);

    // switch (event.keyCode) {
    //   case cc.macro.KEY.up:
    //     GameCtrl.inst.playerCancel(playerInput.Up);
    //     break;
    //   case cc.macro.KEY.down:
    //     GameCtrl.inst.playerCancel(playerInput.Down);
    //     break;
    //   case cc.macro.KEY.left:
    //     GameCtrl.inst.playerCancel(playerInput.Left);
    //     break;
    //   case cc.macro.KEY.right:
    //     GameCtrl.inst.playerCancel(playerInput.Right);
    //     break;
    //   case cc.macro.KEY.space:
    //     break;
    // }
  }

  private openDescView(): void {
    AudioMgr.inst.playSoundLocal('eatGold');
    this.descView.active = true;
  }

  private closeDescView(): void {
    AudioMgr.inst.playSoundLocal('eatGold');
    this.descView.active = false;
  }

  private openDevView(): void {
    AudioMgr.inst.playSoundLocal('eatGold');
    this.devView.active = true;
  }

  private closeDevView(): void {
    AudioMgr.inst.playSoundLocal('eatGold');
    this.devView.active = false;
  }

  private testId: number = 0;
  update(dt) {
    /**
     * 测试模拟下tick
     */
    if (GameCtrl.inst.state == GameState.Run) {
      this.dealMessage();
    }
  }

  private dealMessage(): void {
    const framesData = GameCtrl.inst.getFramesData();
    const len = framesData.length;

    if (len) {
      for (let i = 0; i < len; i++) {
        const mess = framesData[i];
        if (mess) {
          let keys: string[] = Object.keys(mess);
          let infos: pInfo[] = [];
          for (let i: number = 0; i < keys.length; i++) {
            let hid: string = keys[i];
            if (mess[hid].input) {
              let info: pInfo = {
                hid: hid,
                eid: ServerMessage.C2S_PlayerInput,
                input: mess[hid].input,
              };
              infos.push(info);
            } else if (mess[hid].cancel) {
              let info: pInfo = {
                hid: hid,
                eid: ServerMessage.C2S_PlayerCancel,
                input: mess[hid].cancel,
              };
              infos.push(info);
            }
          }
          this.tick(infos);
        }
      }
    }
  }

  /**
   * 帧同步处理逻辑
   */
  public tick(infos) {
    if (infos.length > 0) {
      // console.log(`第 ${gameData.frameCount} 帧得到数据`, infos);
    }
    if (infos) {
      gameData.frameCount++;
      this.mapView.tick(infos);
    }
  }
}
